//
// Created by mio on 25-4-10.
//

#ifndef BUFFERWRITER_H
#define BUFFERWRITER_H

#include <queue>
#include <memory>

void WriteUint32BE(char* p, uint32_t value);
void WriteUint32LE(char* p, uint32_t value);
void WriteUint24BE(char* p, uint32_t value);
void WriteUint24LE(char* p, uint32_t value);
void WriteUint16BE(char* p, uint32_t value);
void WriteUint16LE(char* p, uint32_t value);

class BufferWriter
{
public:
    BufferWriter(int capacity = kMaxQueueLen);
    ~BufferWriter() {}

    /**
     * @brief 向缓冲区追加一个数据块（通过 shared_ptr 管理内存）。
     * 这个版本接收一个 shared_ptr，缓冲区将共享这份数据的所有权。
     * @param data 指向数据块的 shared_ptr<char>。
     * @param size 数据块的总大小（字节）。
     * @param index 数据块内开始发送的位置（通常为 0，除非是续传或特殊情况）。
     * @return true 如果成功添加到队列；false 如果队列已满或参数无效。
     */
    bool Append(std::shared_ptr<char> data, uint32_t size, uint32_t index = 0);
    /**
     * @brief 向缓冲区追加一个数据块（通过 const char* 传入）。
     * 这个版本接收一个原始指针，会在内部创建数据的副本并用 shared_ptr 管理。
     * @param data 指向数据块的 const char* 指针。
     * @param size 数据块的大小（字节）。
     * @param index 数据块内开始发送的位置（通常为 0）。
     * @return true 如果成功添加到队列；false 如果队列已满或参数无效。
     */
    bool Append(const char* data, uint32_t size, uint32_t index = 0);
    /**
     * @brief 尝试从缓冲区队首取数据并通过指定的 socket 发送。
     * 会处理部分发送的情况（send 可能只发送了一部分数据）。
     * @param sockfd 要发送数据的 socket 文件描述符。
     * @return 成功发送的字节数；0 如果缓冲区为空或发生 EAGAIN/EINTR (非阻塞模式下正常)；<0 发生其他错误。
     */
    int Send(int sockfd);

    /**
     * @brief 检查缓冲区是否为空。
     * @return true 如果缓冲区为空。
     */
    inline bool IsEmpty() const { return buffer_.empty(); }
    /**
     * @brief 检查缓冲区是否已满（达到最大 Packet 数量）。
     * @return true 如果缓冲区已满。
     */
    inline bool IsFull() const { return ((int)buffer_.size() >= max_queue_length_ ? true : false); }
    inline uint32_t Size() const { (uint32_t)buffer_.size(); }

private:
    /**
     * @brief 内部结构体，用于表示一个待发送的数据包（块）。
     */
    typedef struct
    {
        std::shared_ptr<char> data; // 指向数据内存的智能指针
        uint32_t size;              // 该数据块的总大小
        uint32_t writeIndex;        // 当前已成功发送的位置（偏移量）
    } Packet;

    std::queue<Packet> buffer_;     // 存储待发送 Packet 的队列
    int max_queue_length_ = 0;      // 队列允许的最大 Packet 数量

    // 默认的最大队列长度常量
    static const int kMaxQueueLen = 10000;
};



#endif //BUFFERWRITER_H
